package com.bookrecomm.service.impl;

import com.bookrecomm.dao.RoleRepository;
import com.bookrecomm.dao.UserRepository;
import com.bookrecomm.dto.UserLoginDTO;
import com.bookrecomm.dto.UserRegisterDTO;
import com.bookrecomm.entity.Role;
import com.bookrecomm.entity.User;
import com.bookrecomm.service.UserService;
import com.bookrecomm.utils.JwtUtils;
import com.bookrecomm.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
// 已移除不需要的密码编码器导入
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashSet;
// 移除未使用的Optional导入
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 * 实现用户相关的业务逻辑
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    // 已移除未使用的passwordEncoder字段

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 用户注册
     * @param registerDTO 注册信息
     * @return 注册成功的用户信息
     */
    @Override
    @Transactional
    public UserVO register(UserRegisterDTO registerDTO) {
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(registerDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查邮箱是否已存在
        if (registerDTO.getEmail() != null && !registerDTO.getEmail().isEmpty() && userRepository.existsByEmail(registerDTO.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }

        // 检查手机号是否已存在
        if (registerDTO.getPhone() != null && !registerDTO.getPhone().isEmpty() && userRepository.existsByPhone(registerDTO.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 检查两次密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            throw new RuntimeException("两次密码不一致");
        }

        // 创建新用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(registerDTO.getPassword()); // 直接使用明文密码
        user.setNickname(registerDTO.getNickname() != null ? registerDTO.getNickname() : registerDTO.getUsername());
        user.setEmail(registerDTO.getEmail());
        user.setPhone(registerDTO.getPhone());
        user.setStatus(1); // 正常状态
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        // 分配默认角色（普通用户）
        Role userRole = roleRepository.findByName("ROLE_USER")
                .orElseThrow(() -> new RuntimeException("默认角色不存在"));
        Set<Role> roles = new HashSet<>();
        roles.add(userRole);
        user.setRoles(roles);

        // 保存用户
        User savedUser = userRepository.save(user);

        // 转换为VO对象并返回
        return convertToUserVO(savedUser, null);
    }

    /**
     * 用户登录
     * @param loginDTO 登录信息
     * @return 登录成功的用户信息（包含令牌）
     */
    @Override
    public UserVO login(UserLoginDTO loginDTO) {
        try {
            System.out.println("开始登录处理，账号: " + loginDTO.getAccount());
            
            // 打印前端传递的原始密码（仅用于调试）
            System.out.println("前端传递的原始密码: " + loginDTO.getPassword());
            
            // 测试密码是否匹配
            testPasswordMatching(loginDTO.getAccount(), loginDTO.getPassword());
            
            // 先查询用户是否存在
            User user = null;
            try {
                user = userRepository.findByUsername(loginDTO.getAccount())
                    .orElseThrow(() -> new RuntimeException("用户不存在"));
                System.out.println("用户存在，ID: " + user.getId() + ", 用户名: " + user.getUsername());
                System.out.println("数据库中的密码: " + user.getPassword());
                System.out.println("用户角色: " + user.getRoles().stream()
                    .map(role -> role.getName())
                    .collect(Collectors.joining(", ")));
                
                // 临时解决方案：直接更新用户密码为明文
                user.setPassword("123456");
                userRepository.save(user);
                System.out.println("已更新用户密码为明文: 123456");
                
            } catch (Exception e) {
                System.out.println("查询用户时出错: " + e.getMessage());
                e.printStackTrace();
                throw new RuntimeException("登录失败: " + e.getMessage());
            }
            
            // 尝试认证
            System.out.println("尝试认证...");
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(loginDTO.getAccount(), loginDTO.getPassword())
            );
            System.out.println("认证成功!");

            // 认证成功，设置认证信息
            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 生成JWT令牌
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            System.out.println("获取到UserDetails，用户名: " + userDetails.getUsername());
            System.out.println("用户权限: " + userDetails.getAuthorities().stream()
                .map(auth -> auth.getAuthority())
                .collect(Collectors.joining(", ")));
                
            String token = jwtUtils.generateToken(userDetails);
            System.out.println("JWT令牌生成成功");

            // 更新最后登录时间
            user.setLastLoginAt(LocalDateTime.now());
            userRepository.save(user);
            System.out.println("用户最后登录时间已更新");

            // 转换为VO对象并返回
            UserVO userVO = convertToUserVO(user, token);
            System.out.println("登录成功，返回用户信息");
            return userVO;
        } catch (BadCredentialsException e) {
            System.out.println("认证失败: 用户名或密码错误");
            e.printStackTrace();
            throw new RuntimeException("用户名或密码错误");
        } catch (Exception e) {
            System.out.println("登录过程中发生异常: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("登录失败: " + e.getMessage());
        }
    }

    /**
     * 根据用户名查询用户
     * @param username 用户名
     * @return 用户信息
     */
    @Override
    public User findByUsername(String username) {
        return userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
    }

    /**
     * 根据ID查询用户
     * @param id 用户ID
     * @return 用户信息
     */
    @Override
    public UserVO findById(Long id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        return convertToUserVO(user, null);
    }

    /**
     * 更新用户信息
     * @param id 用户ID
     * @param user 用户信息
     * @return 更新后的用户信息
     */
    @Override
    @Transactional
    public UserVO updateUser(Long id, User userUpdate) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 检查邮箱是否已存在
        if (userUpdate.getEmail() != null && !userUpdate.getEmail().isEmpty() && 
            !userUpdate.getEmail().equals(user.getEmail()) && 
            userRepository.existsByEmail(userUpdate.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }

        // 检查手机号是否已存在
        if (userUpdate.getPhone() != null && !userUpdate.getPhone().isEmpty() && 
            !userUpdate.getPhone().equals(user.getPhone()) && 
            userRepository.existsByPhone(userUpdate.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 更新用户信息（不更新密码和用户名）
        if (userUpdate.getNickname() != null) {
            user.setNickname(userUpdate.getNickname());
        }
        if (userUpdate.getEmail() != null) {
            user.setEmail(userUpdate.getEmail());
        }
        if (userUpdate.getPhone() != null) {
            user.setPhone(userUpdate.getPhone());
        }
        if (userUpdate.getAvatarUrl() != null) {
            user.setAvatarUrl(userUpdate.getAvatarUrl());
        }
        if (userUpdate.getGender() != null) {
            user.setGender(userUpdate.getGender());
        }
        if (userUpdate.getBirthday() != null) {
            user.setBirthday(userUpdate.getBirthday());
        }
        if (userUpdate.getBio() != null) {
            user.setBio(userUpdate.getBio());
        }
        user.setUpdatedAt(LocalDateTime.now());

        // 保存用户
        User savedUser = userRepository.save(user);

        // 转换为VO对象并返回
        return convertToUserVO(savedUser, null);
    }

    /**
     * 更新用户密码
     * @param id 用户ID
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 是否更新成功
     */
    @Override
    @Transactional
    public boolean updatePassword(Long id, String oldPassword, String newPassword) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 验证旧密码（直接比较明文密码）
        if (!oldPassword.equals(user.getPassword())) {
            throw new RuntimeException("旧密码错误");
        }

        // 更新密码（直接存储明文密码）
        user.setPassword(newPassword);
        user.setUpdatedAt(LocalDateTime.now());
        userRepository.save(user);

        return true;
    }

    /**
     * 获取当前登录用户信息
     * @return 当前用户信息
     */
    @Override
    public UserVO getCurrentUser() {
        // 获取当前认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new RuntimeException("未登录");
        }

        // 获取用户名
        String username = authentication.getName();

        // 查询用户
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 转换为VO对象并返回
        return convertToUserVO(user, null);
    }

    /**
     * 检查用户名是否已存在
     * @param username 用户名
     * @return 是否存在
     */
    @Override
    public boolean existsByUsername(String username) {
        return userRepository.existsByUsername(username);
    }

    /**
     * 检查邮箱是否已存在
     * @param email 邮箱
     * @return 是否存在
     */
    @Override
    public boolean existsByEmail(String email) {
        return userRepository.existsByEmail(email);
    }

    /**
     * 检查手机号是否已存在
     * @param phone 手机号
     * @return 是否存在
     */
    @Override
    public boolean existsByPhone(String phone) {
        return userRepository.existsByPhone(phone);
    }

    /**
     * 测试密码是否匹配
     * 该方法仅用于调试目的
     * 
     * @param username 用户名
     * @param password 前端传递的密码
     */
    private void testPasswordMatching(String username, String password) {
        try {
            // 获取数据库中的用户
            User user = userRepository.findByUsername(username).orElse(null);
            if (user == null) {
                System.out.println("测试密码匹配: 用户不存在");
                return;
            }
            
            // 获取数据库中的密码
            String dbPassword = user.getPassword();
            System.out.println("测试密码匹配 - 数据库密码: " + dbPassword);
            
            // 直接比较明文密码
            boolean matches = password.equals(dbPassword);
            System.out.println("密码匹配结果: " + matches);
            
            // 测试常见密码
            String[] commonPasswords = {"123456", "admin", "password", "admin123", "123456789"};
            System.out.println("测试常见密码是否匹配:");
            for (String commonPassword : commonPasswords) {
                boolean commonMatches = commonPassword.equals(dbPassword);
                System.out.println("密码 '" + commonPassword + "' 匹配结果: " + commonMatches);
            }
            
            // 生成SQL更新语句
            System.out.println("重置密码SQL: UPDATE users SET password = '123456' WHERE username = '" + username + "';");
            
        } catch (Exception e) {
            System.out.println("测试密码匹配时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 将用户实体转换为VO对象
     * @param user 用户实体
     * @param token JWT令牌
     * @return 用户VO对象
     */
    private UserVO convertToUserVO(User user, String token) {
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        
        // 设置角色
        if (user.getRoles() != null) {
            userVO.setRoles(user.getRoles().stream()
                    .map(Role::getName)
                    .collect(Collectors.toSet()));
        }
        
        // 设置统计数据
        userVO.setReadCount(user.getReadHistories() != null ? (long) user.getReadHistories().size() : 0L);
        userVO.setFavoriteCount(user.getFavorites() != null ? (long) user.getFavorites().size() : 0L);
        userVO.setCommentCount(user.getComments() != null ? (long) user.getComments().size() : 0L);
        
        // 计算总阅读时长
        if (user.getReadHistories() != null) {
            userVO.setTotalReadTime(user.getReadHistories().stream()
                    .mapToLong(readHistory -> readHistory.getReadTime() != null ? readHistory.getReadTime() : 0L)
                    .sum());
        } else {
            userVO.setTotalReadTime(0L);
        }
        
        // 设置令牌
        userVO.setToken(token);
        
        // 手机号脱敏处理
        if (userVO.getPhone() != null && userVO.getPhone().length() == 11) {
            userVO.setPhone(userVO.getPhone().substring(0, 3) + "****" + userVO.getPhone().substring(7));
        }
        
        return userVO;
    }
}
